package com.zy;

import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.TokenWindowChatMemory;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import dev.langchain4j.model.openai.OpenAiTokenCountEstimator;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import static dev.langchain4j.model.openai.OpenAiChatModelName.GPT_4_O_MINI;

/**
 * @program: AI_langchain4j
 * @description: chat memory
 * @author: zy
 * @create: 2025-06-28 16:12
 */
public class _08_Memory {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        String apiKey = System.getenv("OPEN_AI_KEY");

        OpenAiStreamingChatModel model = OpenAiStreamingChatModel.builder()
                .apiKey(apiKey)
                .modelName("deepseek-chat")
                .baseUrl("https://api.deepseek.com")    //deepseek的API地址
                .logRequests(true)
               // .logResponses(true)
                .build();

        //创建对话记忆对象， 它的作用是存储对话的历史记录， 并在对话中使用。这里基于 Token
        ChatMemory chatMemory=TokenWindowChatMemory.withMaxTokens(1000, new OpenAiTokenCountEstimator(  GPT_4_O_MINI     ));

        //系统提示词
        SystemMessage systemMessage= SystemMessage.from(  "你是一个高级java工程师，目前正在开发一个电子商务平台，这个平台用java做后台开发语言，oracle数据库, spring data jpa做为dao层的实现，现在你对外提供一些项目的咨询服务. "  );
        chatMemory.add(   systemMessage);  //保存系统 消息

        //用户消息
        UserMessage userMessage= UserMessage.from(  "你好，我想了解一下这个项目的技术栈,并请谈谈数据库中对于大规模电商平台的优化策略，请用最多3到5行描述一下. "  );
        chatMemory.add(   userMessage);  //保存用户消息

        System.out.println("用户消息:"  + userMessage.singleText() );

        AiMessage aiMessage1= streamChat(   model,   chatMemory);
        chatMemory.add(   aiMessage1);  //保存AI 模型回复的  消息

        UserMessage userMessage2= UserMessage.from(  "请些优化策略的具体实现的案例，请用最多5到10行描述一下. "  );
        chatMemory.add(  userMessage2 );

        AiMessage aiMessage2= streamChat(   model,   chatMemory );   //再次发出问题，等待大模型回复，请注意，大模型会根据之前的对话历史记录来回答问题。
        chatMemory.add(   aiMessage2);  //保存AI 模型回复的  消息
    }


    private static AiMessage streamChat(   OpenAiStreamingChatModel model,
                                          ChatMemory chatMemory ) throws ExecutionException, InterruptedException {
        CompletableFuture<AiMessage> responseFuture = new CompletableFuture<>();
        //String prompt="请告诉我什么是RAG";   //这是普通 提示词，没有用模板
        model.chat(     chatMemory.messages(), new StreamingChatResponseHandler() {
            @Override
            public void onPartialResponse(String s) {
                System.out.print(s);    //输出到控制台
            }

            @Override
            public void onCompleteResponse(ChatResponse chatResponse) {
               // System.out.println("Done streaming:"+ chatResponse.toString());
                responseFuture.complete(   chatResponse.aiMessage()     );
            }

            @Override
            public void onError(Throwable throwable) {
               // System.out.println("Error streaming");
               // throwable.printStackTrace();
                responseFuture.completeExceptionally(   throwable );   //异常时的处理
            }
        });
        return responseFuture.get();
    }

}
